package com.hyh.admin.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hyh.ad.common.annotation.Log;
import com.hyh.ad.common.core.domain.entity.SysOperLog;
import com.hyh.ad.common.enums.BusinessType;
import com.hyh.ad.common.utils.SecurityUtils;
import com.hyh.ad.common.utils.ip.IpUtil;
import com.hyh.admin.sys.service.ISysOperLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 操作日志记录切面
 * @author hyh
 * @date 2024-06-012
 */
@Aspect
@Component
public class OperationLogAspect {
    @Autowired
    private HttpServletRequest request;

    @Autowired
    private ISysOperLogService operLogService;

    @Pointcut("@annotation(com.hyh.ad.common.annotation.Log)")
    public void operationLogPointCut() {}

    @AfterReturning(pointcut = "operationLogPointCut()")
    public void afterReturningLogWrite(JoinPoint joinPoint) {
        handleLog(joinPoint, null);
    }

    @AfterThrowing(pointcut = "operationLogPointCut()", throwing = "e")
    public void afterThrowingLogWrite(JoinPoint joinPoint, Throwable e) {
        handleLog(joinPoint, e);
    }

    private void handleLog(JoinPoint joinPoint, Throwable e) {
        // 创建日志对象
        SysOperLog sysOperLog = new SysOperLog();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);

        String className = joinPoint.getTarget().getClass().getName();
        String methodName = method.getName();
        methodName = className + "." + methodName;

        Object[] args = joinPoint.getArgs();
        ObjectMapper objectMapper = new ObjectMapper();
        String params = "";
        try {
            params = objectMapper.writeValueAsString(args);
        } catch (JsonProcessingException jsonProcessingException) {
            jsonProcessingException.printStackTrace();
        }

        BusinessType businessName = log.businessName();
        String operationModule = log.operationModule();
        String username = SecurityUtils.getLoginUser().getUsername();
        String ipAddress = IpUtil.getIpAddr(request);

        sysOperLog.setTitle(operationModule);
        sysOperLog.setBusinessName(String.valueOf(businessName));
        sysOperLog.setMethod(methodName);
        sysOperLog.setOperParam(params);
        sysOperLog.setOperLocation("内网IP");
        sysOperLog.setOperIp(ipAddress);
        sysOperLog.setOperName(username);
        sysOperLog.setOperTime(LocalDateTime.now().plusHours(8));
        sysOperLog.setRequestMethod(request.getMethod());
        sysOperLog.setOperUrl(request.getRequestURI());

        if (e != null) {
            sysOperLog.setStatus(1);
            sysOperLog.setErrorMsg(e.getMessage());
        } else {
            sysOperLog.setStatus(0);
        }

        try {
            operLogService.insert(sysOperLog);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}
